﻿using Mina.Core.Service;
using Mina.Filter.Codec;
using Mina.Filter.Codec.TextLine;
using Mina.Filter.Logging;
using Mina.Filter.Ssl;
using Mina.Transport.Socket;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;

namespace SharpIM
{
    public class IMServer
    {
        public IMServer()
        {

        }
        public IMServerOption Options { get; set; }
        public IMServerState State { get; private set; }
        bool _serverStarted;
        bool _serverShutdownCalled;
        public void Start()
        {
            Start(new IMServerOption());
        }
        public void Start(IMServerOption option)
        {
            if (_serverStarted)
                return;

            this.Options = option;
            IoAcceptor acceptor = new AsyncSocketAcceptor();
            if (option.EnableSsl)
                acceptor.FilterChain.AddLast("ssl", new ServerSslFilter(new X509Certificate2(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "localhost.pfx"), "123456")) { TargetHost = "127.0.0.1:8670" });
            acceptor.FilterChain.AddLast("logger", new LoggingFilter());
            acceptor.FilterChain.AddLast("codec", new ProtocolCodecFilter(new CodecFactory()));
            acceptor.Handler = new MessageHandler();
            acceptor.ExceptionCaught += (o, e) => Console.WriteLine(e.Exception);
            acceptor.SessionIdle += (o, e) => Console.WriteLine("IDLE " + e.Session.GetIdleCount(e.IdleStatus));
            acceptor.SessionDestroyed += (s, e) => Console.WriteLine(e.Session.RemoteEndPoint + $" session {e.Session.Id} destroyed."); ;
            acceptor.SessionClosed += (s, e) => Console.WriteLine(e.Session.RemoteEndPoint + $" session {e.Session.Id} closed."); ;
            acceptor.SessionCreated += (s, e) => Console.WriteLine(e.Session.RemoteEndPoint + $" session {e.Session.Id} created."); ;
            acceptor.SessionOpened += (s, e) => Console.WriteLine(e.Session.RemoteEndPoint + $" session {e.Session.Id} opened."); ;
            acceptor.Bind(new IPEndPoint(option.IpAddress, option.Port));
            _serverStarted = true;
        }
        public void Shutdown()
        {
            if (!_serverStarted)
                return;
            if (_serverShutdownCalled)
                return;
            _serverShutdownCalled = true;
        }
    }
}
